<?php

/**
 *  +----------------------------------------------------------------------
 *  | 文件功能：TopUpController.php：
 *  +----------------------------------------------------------------------
 *  | Copyright (c) 2022~2025 https://www.huihuiv.com All rights reserved. 
 *  +----------------------------------------------------------------------
 *  | Create At: 2025年05月13日 22:01:04
 *  +----------------------------------------------------------------------
 *  | Author: 半壶水 <star@cqshanwen.com>
 *  +----------------------------------------------------------------------
 */

namespace App\Http\Controllers\Api;

use App\Enum\CardRecordCode;
use App\Models\CardModel;
use App\Models\TopUpRecordModel;
use App\Utils\Build;
use App\Utils\HttpRequest;
use App\Utils\Message;
use Carbon\Carbon;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class TopUpController extends BaseController
{
    /**
     * 确认充值
     *
     * @param Request $request
     * @param TopUpRecordModel $topUpRecordModel
     * @return void
     */
    public function confirm_topup(
        Request $request,
        TopUpRecordModel $topUpRecordModel,
        CardModel $cardModel
    ) {
        // 1. 验证手机号
        $phone = $request->input('phone');
        if (empty($phone)) {
            return Message::show_message(false, '手机号码不能为空');
        }

        // 2. 查询充值卡
        $cardInfo = $cardModel->where('phone', $phone)->first();
        if (! $cardInfo) {
            return Message::show_message(false, '请先激活充值卡');
        }
        if ($cardInfo->status == CardRecordCode::NUMBER_NONE_CODE) {
            return Message::show_message(false, '您的充值卡暂无次数，请充值后重试');
        }

        // 3. 判断本月是否已充值（use_time 可能为空）
        if ($cardInfo->use_time) {
            $lastUse = Carbon::parse($cardInfo->use_time);
            if ($lastUse->month === Carbon::now()->month) {
                return Message::show_message(false, '您本月已经充值过，请下个月再试');
            }
        }

        // 4. 构造上游接口请求数据
        $data = [
            'account'       => $phone,
            'out_trade_num' => Build::order_number('HF'),
            'product_id'    => env('TOPUP_PRODUCT_ID'),
            'userid'        => env('TOPUP_ID', ''),
            'notify_url'    => env('TOPUP_NOTIFY_URL', ''),
        ];
        ksort($data);
        $signStr = http_build_query($data) . '&apikey=' . env('TOPUP_APPKEY');
        $data['sign'] = strtoupper(md5(urldecode($signStr)));

        // 5. 调用上游充值接口
        $response = HttpRequest::curl_get(env('TOPUP_API', ''), http_build_query($data));
        $result   = json_decode($response, true);

        if (($result['errno'] ?? 1) !== 0) {
            return Message::show_message(false, '充值失败! ' . ($result['errmsg'] ?? '未知错误'));
        }

        $respData = $result['data'];

        // 6. 手动事务：写明细 + 更新卡片
        try {
            DB::beginTransaction();

            // 6.1 写入充值明细
            $topUpRecordModel->create([
                'order_number'  => $respData['order_number'],
                'mobile'        => $respData['mobile'],
                'product_id'    => $respData['product_id'],
                'total_price'   => $respData['total_price'],
                'out_trade_num' => $respData['out_trade_num'],
                'title'         => $respData['title'],
            ]);

            // 6.2 更新卡片剩余次数和使用时间
            $newRemaining = max(0, $cardInfo->remaining_num - 1);
            $newStatus    = $newRemaining === 0
                ? CardRecordCode::NUMBER_NONE_CODE
                : CardRecordCode::IS_USE_CODE;

            $cardModel->where('phone', $phone)->update([
                'remaining_num' => $newRemaining,
                'status'        => $newStatus,
                'use_time'      => Carbon::now(),
            ]);

            DB::commit();
            return Message::show_message(true, '充值成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return Message::show_message(false, '事务失败：' . $e->getMessage());
        }
    }

    // 响应回调
    public function notify(
        Request $request,
        TopUpRecordModel $topUpRecordModel
    ) {
        $data['order_number'] = $request->get('order_number');
        $data['out_trade_num'] = $request->get('out_trade_num');
        $data['otime'] = $request->get('otime');
        $data['state'] = $request->get('state');
        $data['mobile'] = $request->get('mobile');

        if (!empty($data['out_trade_num'])) { // 返回信息
            // 开启事务
            DB::beginTransaction();
            try {
                $topUpRecordModel->where(['out_trade_num' => $data['out_trade_num']])->update($data);
                DB::commit();
                Log::debug('充值成功:' . json_encode($data));
                echo 'success';
            } catch (Exception $error) {
                DB::rollBack();
                Log::error('充值失败:' . json_encode($error));
                echo 'fail';
            }
        } else {
            echo 'fail';
        }
    }
}
